package org.zizi.service;

import java.util.Map;

import org.directwebremoting.convert.BaseV20Converter;
import org.directwebremoting.convert.BeanConverter;
import org.directwebremoting.convert.StringConverter;
import org.directwebremoting.dwrp.ParseUtil;
import org.directwebremoting.dwrp.ProtocolConstants;
import org.directwebremoting.extend.ConverterManager;
import org.directwebremoting.extend.InboundContext;
import org.directwebremoting.extend.InboundVariable;
import org.directwebremoting.extend.MarshallException;
import org.directwebremoting.util.LocalUtil;
import org.directwebremoting.util.Messages;

public class DwrActionConverter extends BeanConverter
{
	private StringConverter string = new StringConverter();
	private BeanConverter bean = new BeanConverter();
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public Object convertInbound(Class clazz, InboundVariable iv, InboundContext context) throws MarshallException
	{
		String value = iv.getValue();
		if (value == null) return null;
		if (value.trim().equals(ProtocolConstants.INBOUND_NULL)) return null;
		
		if (!value.startsWith(ProtocolConstants.INBOUND_MAP_START))
			throw new MarshallException(clazz, Messages.getString("BeanConverter.FormatError", ProtocolConstants.INBOUND_MAP_START));
		if (!value.endsWith(ProtocolConstants.INBOUND_MAP_END))
			throw new MarshallException(clazz, Messages.getString("BeanConverter.FormatError", ProtocolConstants.INBOUND_MAP_END));
		
		value = value.substring(1, value.length() - 1);
		
		String name = null;
		
		try
		{
			Map<String, String> tokens = extractInboundTokens(clazz, value);
			
			name = tokens.get("name");
			name = (String)convert(String.class, name, string, iv.getLookup(), context);

			//get Action from name
			name = "org.zizi.action." + name;
			Class<?> type = Class.forName(name);
			
			String data = tokens.get("data");
			return convert(type, data, bean, iv.getLookup(), context);
		}
		catch (MarshallException e)
		{
			throw e;
		}
		catch (ClassNotFoundException e)
		{
			//没有找到action
			throw new MarshallException(clazz, e);
		}
		catch (Exception e)
		{
			throw new MarshallException(clazz, e);
		}
	}
	
	@SuppressWarnings("rawtypes")
	private Object convert(Class clazz, String source, BaseV20Converter converter, InboundContext context, InboundContext context2) throws Exception
	{
		String[] split = ParseUtil.splitInbound(source);
		String value = split[LocalUtil.INBOUND_INDEX_VALUE];
		String type = split[LocalUtil.INBOUND_INDEX_TYPE];
		InboundVariable iv = new InboundVariable(context, null, type, value);
		
		return converter.convertInbound(clazz, iv, context2);
	}
	
	public void setConverterManager(ConverterManager converterManager)
	{
		super.setConverterManager(converterManager);
		bean.setConverterManager(converterManager);
	}
}
